// 《围棋》作者版权所有。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// 此文件包含主运行时AIX系统调用。
// 轮询集系统调用在netpoll_aix中。去
// 该实现基于Solaris和Windows。
// 每个系统调用都是通过使用asmcgocall和asmsyscall6 
// 汇编函数调用其libc符号进行的。

package runtime

import (
	"unsafe"
)

// 为_启动函数导入的符号。10月19日，中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府进口进口（中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府的进口进口进口（中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府：中国政府_uuumod_init 


var (
	libc___n_pthreads,
	libc___mod_init libFunc
)

// 系统调用

// go:cgo\u import\u dynamic libc\uuuu Errno\u Errno北京奥运会的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的另一个公共图书馆的另一个公共图书馆的一个公共图书馆的一个公共图书馆的另一个公共图书馆的一个公共图书馆的另一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的第四个公共图书馆的一个公共图书馆的第四个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的一个公共图书馆的第四个公共公共公共：cgo_import_dynamic libc_getsystemcfg中国政府：GoGoGoGoGoGoGoGoGoGoGoGoGoGoGoGoGoGoGoGoGoGoGoGo进口动态lib进口进口动态lib进口动态lib进口动态lib进口动态libc（动态libc（动态libc（动态libc）的动态libc（动态libc（动态libc）的动态libc（动态libc）的动态libc（动态libc（动态libc）的动态libc（动态libc）的动态libc（动态libc（动态libc）的）和（动态libc（动态libc）的）和（动态libc（动态libc）的）的）和（动态libc（动态libc）的）的）和（动态libc）的）和（动态的）的）的（动态的）的）的）和（动态的）的）的）是在在在（北京北京北京的）的）的）在（北京（北京）的）的）的）是在在在（北京）在（北京的）的）的）在（北京）在go:cgo_导入_动态libc_保护北京奥运会上的一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，另一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，一个城市，另一个城市，一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，另一个城市，一个城市，一个城市，一个城市，动态libc_读取“libc.a/shr_64.o”

// go:cgo_import_dynamic libpthread_attr_init中国国家外汇基金管理公司（62
// go：cgo（中国）进口。动态libpt线程（中国）政府的研究结果（中国）的进口。动态libpt线程（中国）政府的cgo（cgo（中国）的进口。动态libpt线程（中国）的进口（中国）的进口。动态libpt线程（中国）的进口（中国）中国政府的研究结果（中国）政府的进口（中国）进口）的动态lib（中国政府的进口（中国）的进口（中国）的进口）的动态libpt线程（中国的线程）创建的线程，并创建线程的线程。创建线程的线程。创建线程的线程。创建线程。创建的线程。创建线程。创建的线程。在创建线程。创建的线程。创建创建的线程。在创建的线程。在创建创建的线程。在创建的线程。在创建的线程。在创建的线程。在创建的线程。在制造制造制造制造的线程。在创建的线程。根据根据根据根据根据根据创建的线程。在创建的线程的线程。在o.

// go:linkname libc_getpid libc_getpid 
// go:linkname libc_getsystemcfg libc_getsystemcfg libc_getsystemcfg 
// go:linkname libc_kill libc_kill 
// go:linkname libc_maddise libc_maddise 
// go:linkname libc_maddise libc_maddise 
// go:linkname libc_munmap libc_munmap 
// go:linkname libc_open libc_open 
// go:linkname libc_setitimer libc_setitimer libc_setitimer 
// go linkname libc_sigaction libc_sigaction 
// go go linkname libc_sigaltstack libc_sigaltstack libc_sigaltstack libc_sigaltstack libc_sysconf 
// go go

// go:linkname libpthread_u_____;pth_init 
// go:linkname libpthread_attr_destroy libpthread_attr_destroy 
// golibpthread_attr_setstacksize 
// go:linkname libpthread_attr_setdetackstate libpthread_attr_setdetackstate 
// go:linkname libpthread_创建libpthread_创建abpthread_创建
// go:linkname libpthread_创建
// go:linkname libpthread_kill libpthread_kill 

var (
	// libc 
	libc__Errno,
	libc_clock_gettime,
	libc_close,
	libc_exit,
	libc_getpid,
	libc_getsystemcfg,
	libc_kill,
	libc_madvise,
	libc_malloc,
	libc_mmap,
	libc_mprotect,
	libc_munmap,
	libc_open,
	libc_pipe,
	libc_raise,
	libc_read,
	libc_sched_yield,
	libc_sem_init,
	libc_sem_post,
	libc_sem_timedwait,
	libc_sem_wait,
	libc_setitimer,
	libc_sigaction,
	libc_sigaltstack,
	libc_sysconf,
	libc_usleep,
	libc_write,
	// libpthread 
	libpthread___pth_init,
	libpthread_attr_destroy,
	libpthread_attr_init,
	libpthread_attr_getstacksize,
	libpthread_attr_setstacksize,
	libpthread_attr_setdetachstate,
	libpthread_attr_setstackaddr,
	libpthread_create,
	libpthread_sigthreadmask,
	libpthread_self,
	libpthread_kill libFunc
)

type libFunc uintptr

// asmssyscall6使用C约定调用libc符号。
// 它在sys_aix_ppc64中定义。去
var asmsyscall6 libFunc

// syscallX函数必须始终使用g！=零和m！=nil，
// 因为它依赖于g.m.libcall将参数传递给asmcgocall。
// 在sys_aix_ppc64中，系统调用没有g或m的少数情况下必须调用其等效的
// 函数。让我们来处理它们。

// go:nowritebarrier 
// go:nosplit 
func syscall0(fn *libFunc) (r, err uintptr) {
	gp := getg()
	mp := gp.m
	resetLibcall := true
	if mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦异步cpu探查器发现
		// 所有三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		resetLibcall = false // 请参阅sys_darwin中的注释。go:libcCall 
	}

	c := libcall{
		fn:   uintptr(unsafe.Pointer(fn)),
		n:    0,
		args: uintptr(unsafe.Pointer(&fn)), // 未使用，但必须为非零，否则崩溃
	}

	asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c))

	if resetLibcall {
		mp.libcallsp = 0
	}

	return c.r1, c.err
}

// go:nowritebarrier 
// go:nosplit 
func syscall1(fn *libFunc, a0 uintptr) (r, err uintptr) {
	gp := getg()
	mp := gp.m
	resetLibcall := true
	if mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦异步cpu探查器发现
		// 所有三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		resetLibcall = false // 请参阅sys_darwin中的注释。go:libcCall 
	}

	c := libcall{
		fn:   uintptr(unsafe.Pointer(fn)),
		n:    1,
		args: uintptr(unsafe.Pointer(&a0)),
	}

	asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c))

	if resetLibcall {
		mp.libcallsp = 0
	}

	return c.r1, c.err
}

// go:nowritebarrier 
// go:nosplit 
// go:cgo_unsafe_args 
func syscall2(fn *libFunc, a0, a1 uintptr) (r, err uintptr) {
	gp := getg()
	mp := gp.m
	resetLibcall := true
	if mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦async cpu profiler发现
		// 这三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		resetLibcall = false // 请参阅sys_darwin中的注释。go:libcCall 
	}

	c := libcall{
		fn:   uintptr(unsafe.Pointer(fn)),
		n:    2,
		args: uintptr(unsafe.Pointer(&a0)),
	}

	asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c))

	if resetLibcall {
		mp.libcallsp = 0
	}

	return c.r1, c.err
}

// go:nowritebarrier 
// go:nosplit 
// go:cgo_unsafe_args 
func syscall3(fn *libFunc, a0, a1, a2 uintptr) (r, err uintptr) {
	gp := getg()
	mp := gp.m
	resetLibcall := true
	if mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦async cpu profiler发现
		// 所有三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		resetLibcall = false // 请参阅sys darwin中的注释。go:libcCall 
	}

	c := libcall{
		fn:   uintptr(unsafe.Pointer(fn)),
		n:    3,
		args: uintptr(unsafe.Pointer(&a0)),
	}

	asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c))

	if resetLibcall {
		mp.libcallsp = 0
	}

	return c.r1, c.err
}

// go:nowritebarrier 
// go:nosplit 
// go:cgo_unsafe_args 
func syscall4(fn *libFunc, a0, a1, a2, a3 uintptr) (r, err uintptr) {
	gp := getg()
	mp := gp.m
	resetLibcall := true
	if mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦async cpu profiler发现
		// 所有三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		resetLibcall = false // 请参阅sys_darwin中的注释。go:libcCall 
	}

	c := libcall{
		fn:   uintptr(unsafe.Pointer(fn)),
		n:    4,
		args: uintptr(unsafe.Pointer(&a0)),
	}

	asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c))

	if resetLibcall {
		mp.libcallsp = 0
	}

	return c.r1, c.err
}

// go:nowritebarrier 
// go:nosplit 
// go:cgo_unsafe_args 
func syscall5(fn *libFunc, a0, a1, a2, a3, a4 uintptr) (r, err uintptr) {
	gp := getg()
	mp := gp.m
	resetLibcall := true
	if mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦async cpu profiler发现
		// 这三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		resetLibcall = false // 请参阅sys_darwin中的注释。go:libcCall 
	}

	c := libcall{
		fn:   uintptr(unsafe.Pointer(fn)),
		n:    5,
		args: uintptr(unsafe.Pointer(&a0)),
	}

	asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c))

	if resetLibcall {
		mp.libcallsp = 0
	}

	return c.r1, c.err
}

// go:nowritebarrier 
// go:nosplit 
// go:cgo_unsafe_args 
func syscall6(fn *libFunc, a0, a1, a2, a3, a4, a5 uintptr) (r, err uintptr) {
	gp := getg()
	mp := gp.m
	resetLibcall := true
	if mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦async cpu profiler发现
		// 这三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		resetLibcall = false // 请参阅sys u darwin中的注释。go:libcCall 
	}

	c := libcall{
		fn:   uintptr(unsafe.Pointer(fn)),
		n:    6,
		args: uintptr(unsafe.Pointer(&a0)),
	}

	asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c))

	if resetLibcall {
		mp.libcallsp = 0
	}

	return c.r1, c.err
}

func exit1(code int32)

// go:nosplit 
func exit(code int32) {
	_g_ := getg()

	// 检查g的有效性，因为在
	// newosproc0期间没有g。
	if _g_ != nil {
		syscall1(&libc_exit, uintptr(code))
		return
	}
	exit1(code)
}

func write2(fd, p uintptr, n int32) int32

// go:nosplit 
func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
	_g_ := getg()

	// 检查g的有效性，因为在
	// newosproc0期间没有g。
	if _g_ != nil {
		r, errno := syscall3(&libc_write, uintptr(fd), uintptr(p), uintptr(n))
		if int32(r) < 0 {
			return -int32(errno)
		}
		return int32(r)
	}
	// 请注意，在这种情况下，我们无法返回有效的errno值。
	return write2(fd, uintptr(p), n)

}

// go:nosplit 
func read(fd int32, p unsafe.Pointer, n int32) int32 {
	r, errno := syscall3(&libc_read, uintptr(fd), uintptr(p), uintptr(n))
	if int32(r) < 0 {
		return -int32(errno)
	}
	return int32(r)
}

// go:nosplit 
func open(name *byte, mode, perm int32) int32 {
	r, _ := syscall3(&libc_open, uintptr(unsafe.Pointer(name)), uintptr(mode), uintptr(perm))
	return int32(r)
}

// go:nosplit 
func closefd(fd int32) int32 {
	r, _ := syscall1(&libc_close, uintptr(fd))
	return int32(r)
}

// go:nosplit 
func pipe() (r, w int32, errno int32) {
	var p [2]int32
	_, err := syscall1(&libc_pipe, uintptr(noescape(unsafe.Pointer(&p[0]))))
	return p[0], p[1], int32(err)
}

// mmap调用mmap系统调用。
// 我们只将文件偏移量的低32位传递给
// 组装程序；汇编例程应将较高的位（如果需要）提供为0。
// 错误结果是一个操作系统错误代码，如ENOMEM。
// go:nosplit 
func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
	r, err0 := syscall6(&libc_mmap, uintptr(addr), uintptr(n), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(off))
	if r == ^uintptr(0) {
		return nil, int(err0)
	}
	return unsafe.Pointer(r), int(err0)
}

// go:nosplit 
func mprotect(addr unsafe.Pointer, n uintptr, prot int32) (unsafe.Pointer, int) {
	r, err0 := syscall3(&libc_mprotect, uintptr(addr), uintptr(n), uintptr(prot))
	if r == ^uintptr(0) {
		return nil, int(err0)
	}
	return unsafe.Pointer(r), int(err0)
}

// go:nosplit 
func munmap(addr unsafe.Pointer, n uintptr) {
	r, err := syscall2(&libc_munmap, uintptr(addr), uintptr(n))
	if int32(r) == -1 {
		println("syscall munmap failed: ", hex(err))
		throw("syscall munmap")
	}
}

// go:nosplit 
func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
	r, err := syscall3(&libc_madvise, uintptr(addr), uintptr(n), uintptr(flags))
	if int32(r) == -1 {
		println("syscall madvise failed: ", hex(err))
		throw("syscall madvise")
	}
}

func sigaction1(sig, new, old uintptr)

// go:nosplit 
func sigaction(sig uintptr, new, old *sigactiont) {
	_g_ := getg()

	// 。libpreinit。
	if _g_ != nil {
		r, err := syscall3(&libc_sigaction, sig, uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old)))
		if int32(r) == -1 {
			println("Sigaction failed for sig: ", sig, " with error:", hex(err))
			throw("syscall sigaction")
		}
		return
	}

	sigaction1(sig, uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old)))
}

// go:nosplit 
func sigaltstack(new, old *stackt) {
	r, err := syscall2(&libc_sigaltstack, uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old)))
	if int32(r) == -1 {
		println("syscall sigaltstack failed: ", hex(err))
		throw("syscall sigaltstack")
	}
}

// go:nosplit 
// go:linkname internal\u cpu\u getsystemcfg internal/cpu。getsystemcfg 
func internal_cpu_getsystemcfg(label uint) uint {
	r, _ := syscall1(&libc_getsystemcfg, uintptr(label))
	return uint(r)
}

func usleep1(us uint32)

// go:nosplit 
func usleep_no_g(us uint32) {
	usleep1(us)
}

// go:nosplit 
func usleep(us uint32) {
	r, err := syscall1(&libc_usleep, uintptr(us))
	if int32(r) == -1 {
		println("syscall usleep failed: ", hex(err))
		throw("syscall usleep")
	}
}

// go:nosplit 
func clock_gettime(clockid int32, tp *timespec) int32 {
	r, _ := syscall2(&libc_clock_gettime, uintptr(clockid), uintptr(unsafe.Pointer(tp)))
	return int32(r)
}

// go:nosplit 
func setitimer(mode int32, new, old *itimerval) {
	r, err := syscall3(&libc_setitimer, uintptr(mode), uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old)))
	if int32(r) == -1 {
		println("syscall setitimer failed: ", hex(err))
		throw("syscall setitimer")
	}
}

// go nosplit 
func malloc(size uintptr) unsafe.Pointer {
	r, _ := syscall1(&libc_malloc, size)
	return unsafe.Pointer(r)
}

// go nosplit 
func sem_init(sem *semt, pshared int32, value uint32) int32 {
	r, _ := syscall3(&libc_sem_init, uintptr(unsafe.Pointer(sem)), uintptr(pshared), uintptr(value))
	return int32(r)
}

func sem_wait(sem *semt) (int32, int32) {
	r, err := syscall1(&libc_sem_wait, uintptr(unsafe.Pointer(sem)))
	return int32(r), int32(err)
}

func sem_post(sem *semt) int32 {
	r, _ := syscall1(&libc_sem_post, uintptr(unsafe.Pointer(sem)))
	return int32(r)
}

func sem_timedwait(sem *semt, timeout *timespec) (int32, int32) {
	r, err := syscall2(&libc_sem_timedwait, uintptr(unsafe.Pointer(sem)), uintptr(unsafe.Pointer(timeout)))
	return int32(r), int32(err)
}

func raise(sig uint32) {
	r, err := syscall1(&libc_raise, uintptr(sig))
	if int32(r) == -1 {
		println("syscall raise failed: ", hex(err))
		throw("syscall raise")
	}
}

func raiseproc(sig uint32) {
	pid, err := syscall0(&libc_getpid)
	if int32(pid) == -1 {
		println("syscall getpid failed: ", hex(err))
		throw("syscall raiseproc")
	}

	syscall2(&libc_kill, pid, uintptr(sig))
}

func osyield1()

func osyield_no_g() {
	osyield1()
}

func osyield() {
	r, err := syscall0(&libc_sched_yield)
	if int32(r) == -1 {
		println("syscall osyield failed: ", hex(err))
		throw("syscall osyield")
	}
}

// go:nosplit 
func sysconf(name int32) uintptr {
	r, _ := syscall1(&libc_sysconf, uintptr(name))
	if int32(r) == -1 {
		throw("syscall sysconf")
	}
	return r

}

// pthread函数在主返回值
// 因此，err通过syscall返回意味着什么，也不能使用

func pthread_attr_destroy(attr *pthread_attr) int32 {
	r, _ := syscall1(&libpthread_attr_destroy, uintptr(unsafe.Pointer(attr)))
	return int32(r)
}

func pthread_attr_init1(attr uintptr) int32

// go:nosplit 
func pthread_attr_init(attr *pthread_attr) int32 {
	_g_ := getg()

	// 检查g的有效性，因为在
	// newosproc0期间没有g。
	if _g_ != nil {
		r, _ := syscall1(&libpthread_attr_init, uintptr(unsafe.Pointer(attr)))
		return int32(r)
	}

	return pthread_attr_init1(uintptr(unsafe.Pointer(attr)))
}

func pthread_attr_setdetachstate1(attr uintptr, state int32) int32

// go:nosplit 
func pthread_attr_setdetachstate(attr *pthread_attr, state int32) int32 {
	_g_ := getg()

	// 检查g的有效性，因为在
	// newosproc0期间没有g。
	if _g_ != nil {
		r, _ := syscall2(&libpthread_attr_setdetachstate, uintptr(unsafe.Pointer(attr)), uintptr(state))
		return int32(r)
	}

	return pthread_attr_setdetachstate1(uintptr(unsafe.Pointer(attr)), state)
}

// go:nosplit 
func pthread_attr_setstackaddr(attr *pthread_attr, stk unsafe.Pointer) int32 {
	r, _ := syscall2(&libpthread_attr_setstackaddr, uintptr(unsafe.Pointer(attr)), uintptr(stk))
	return int32(r)
}

// go:nosplit 
func pthread_attr_getstacksize(attr *pthread_attr, size *uint64) int32 {
	r, _ := syscall2(&libpthread_attr_getstacksize, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(size)))
	return int32(r)
}

func pthread_attr_setstacksize1(attr uintptr, size uint64) int32

// go:nosplit 
func pthread_attr_setstacksize(attr *pthread_attr, size uint64) int32 {
	_g_ := getg()

	// 检查g的有效性，因为在
	// newosproc0期间没有g。
	if _g_ != nil {
		r, _ := syscall2(&libpthread_attr_setstacksize, uintptr(unsafe.Pointer(attr)), uintptr(size))
		return int32(r)
	}

	return pthread_attr_setstacksize1(uintptr(unsafe.Pointer(attr)), size)
}

func pthread_create1(tid, attr, fn, arg uintptr) int32

// go:nosplit 
func pthread_create(tid *pthread, attr *pthread_attr, fn *funcDescriptor, arg unsafe.Pointer) int32 {
	_g_ := getg()

	// 检查g的有效性，因为在
	// newosproc0期间没有g。
	if _g_ != nil {
		r, _ := syscall4(&libpthread_create, uintptr(unsafe.Pointer(tid)), uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(fn)), uintptr(arg))
		return int32(r)
	}

	return pthread_create1(uintptr(unsafe.Pointer(tid)), uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(fn)), uintptr(arg))
}

// 在多线程程序中，不能调用sigprocmask。
// 它被sigthreadmask取代。
func sigprocmask1(how, new, old uintptr)

// go:nosplit 
func sigprocmask(how int32, new, old *sigset) {
	_g_ := getg()

	// 检查m的有效性，因为它可能在cgo 
	// 回调过程中被调用，在m还不可用的情况下足够早。
	if _g_ != nil && _g_.m != nil {
		r, err := syscall3(&libpthread_sigthreadmask, uintptr(how), uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old)))
		if int32(r) != 0 {
			println("syscall sigthreadmask failed: ", hex(err))
			throw("syscall sigthreadmask")
		}
		return
	}
	sigprocmask1(uintptr(how), uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old)))

}

// go:nosplit 
func pthread_self() pthread {
	r, _ := syscall0(&libpthread_self)
	return pthread(r)
}

// go:nosplit 
func signalM(mp *m, sig int) {
	syscall2(&libpthread_kill, uintptr(pthread(mp.procid)), uintptr(sig))
}
